package main

import (
	"context"
	"log"
	"net/http"
	"time"

	"math/rand"

	"github.com/gorilla/websocket"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"

	"example/game/config"
	"example/game/routes"
)

var upgrader = websocket.Upgrader{
	HandshakeTimeout: 0,
	ReadBufferSize:   0,
	WriteBufferSize:  0,
	WriteBufferPool:  nil,
	Subprotocols:     []string{},
	Error: func(w http.ResponseWriter, r *http.Request, status int, reason error) {
	},
	CheckOrigin: func(r *http.Request) bool {
		return true
	},
	EnableCompression: false,
}

type User struct {
	Name                 string  `bson:"name"`
	Level                int     `bson:"level"`
	Experience           float64 `bson:"experience"`
	HealthPoints         int     `bson:"hp"`
	ManaPoints           int     `bson:"mp"`
	Attack               int     `bson:"attack"`
	Defense              int     `bson:"defense"`
	Speed                int     `bson:"speed"`
	Spirit               int     `bson:"spirit"`
	Comprehension        int     `bson:"comprehension"`
	CultivationTechnique string  `bson:"cultivation_technique"`
	LevelName            string  `bson:"level_name"` // 修仙等级的名称。
}

func main() {
	// 初始化路由
	r := routes.InitRouter()

	// WebSocket 路由
	r.HandleFunc("/ws", websocketHandler)

	// 启动 HTTP 服务器
	log.Printf("Server started on port %s", config.DefaultPort)
	err := http.ListenAndServe(":"+config.DefaultPort, r)
	if err != nil {
		log.Fatal("Server failed to start: ", err)
	}
}

func websocketHandler(w http.ResponseWriter, r *http.Request) {
	conn, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Println("WebSocket upgrade failed:", err)
		return
	}
	defer conn.Close()

	// 读取用户名
	username := r.URL.Query().Get("user")

	// 连接 MongoDB
	clientOptions := options.Client().ApplyURI(config.MongoDBURL)
	client, err := mongo.Connect(context.TODO(), clientOptions)
	if err != nil {
		log.Println("MongoDB connection failed:", err)
		return
	}

	// 获取用户集合
	collection := client.Database("game_dev").Collection("users")
	cultivationLevels := client.Database("game_dev").Collection("cultivation_levels")

	// 启动轮询任务
	pollForChanges(collection, cultivationLevels, username, conn)

	// 关闭 MongoDB 客户端连接
	client.Disconnect(context.TODO())
}

func createNewUser(username string) User {
	// Randomly initialize user attributes
	return User{
		Name:                 username,
		Level:                0,
		LevelName:            "肉胎", // 默认为肉胎
		Experience:           0,
		HealthPoints:         rand.Intn(10) + 50, // Random HP between 50 and 60
		ManaPoints:           rand.Intn(10) + 30, // Random MP between 30 and 40
		Attack:               rand.Intn(5) + 5,   // Random Attack between 5 and 10
		Defense:              rand.Intn(5) + 5,   // Random Defense between 5 and 10
		Speed:                rand.Intn(5) + 5,   // Random Speed between 5 and 10
		Spirit:               rand.Intn(5) + 5,   // Random Spirit between 5 and 10
		Comprehension:        rand.Intn(5) + 5,   // Random Comprehension between 5 and 10
		CultivationTechnique: "基础法门",             // Default cultivation technique
	}
}

func updateLevel(user *User, collection *mongo.Collection) *User {
	// 查询数据库获取所有等级数据
	var levels []struct {
		Level      int     `bson:"level"`
		Name       string  `bson:"name"`
		Experience float64 `bson:"experience"`
	}
	cursor, err := collection.Find(context.Background(), bson.M{})
	if err != nil {
		log.Printf("Error getting levels from database: %v", err)
		return user
	}
	defer cursor.Close(context.Background())
	if err = cursor.All(context.Background(), &levels); err != nil {
		log.Printf("Error decoding levels: %v", err)
		return user
	}

	// 根据用户的经验值更新等级
	var newLevel int
	var newLevelName string
	for _, lvl := range levels {
		if user.Experience >= lvl.Experience {
			newLevel = lvl.Level
			newLevelName = lvl.Name
		} else {
			break
		}
	}

	// 只有在新等级比当前等级高时才更新用户等级
	if newLevel > user.Level {
		user.Level = newLevel
		user.LevelName = newLevelName
	}

	return user
}

func pollForChanges(collection *mongo.Collection, cultivationLevels *mongo.Collection, username string, conn *websocket.Conn) {
	ticker := time.NewTicker(1 * time.Second)
	defer ticker.Stop()

	for range ticker.C {
		// 查询数据库获取用户信息
		filter := bson.M{"name": username}
		var user User
		err := collection.FindOne(context.Background(), filter).Decode(&user)
		if err != nil {
			if err == mongo.ErrNoDocuments {
				// 用户不存在，创建新用户
				newUser := createNewUser(username)
				_, err := collection.InsertOne(context.Background(), newUser)
				if err != nil {
					log.Printf("Error inserting new user: %v", err)
					continue
				}
				user = newUser
			} else {
				log.Printf("Error finding user: %v", err)
				continue
			}
		}

		// 增加经验值
		user.Experience += 2

		// 根据经验值更新用户等级
		user = *updateLevel(&user, cultivationLevels)

		// 更新数据库中用户的信息
		update := bson.M{
			"$set": bson.M{
				"level":                 user.Level,
				"experience":            user.Experience,
				"health_points":         user.HealthPoints,
				"mana_points":           user.ManaPoints,
				"attack":                user.Attack,
				"defense":               user.Defense,
				"speed":                 user.Speed,
				"spirit":                user.Spirit,
				"comprehension":         user.Comprehension,
				"cultivation_technique": user.CultivationTechnique,
				"level_name":            user.LevelName,
			},
		}
		_, err = collection.UpdateOne(context.Background(), filter, update)
		if err != nil {
			log.Printf("Error updating user: %v", err)
			continue
		}

		// 将更新后的用户数据发送给客户端
		if err := conn.WriteJSON(user); err != nil {
			log.Printf("Error sending user data to client: %v", err)
			return
		}
	}
}
